home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / ADA / GNAT / !gcc / adainc / 3 / adb / i-cobol < prev    next >
Text File  |  1996-02-12  |  28KB  |  976 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT COMPILER COMPONENTS                         --
  4. --                                                                          --
  5. --                     I N T E R F A C E S . C O B O L                      --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.8 $                              --
  10. --                                                                          --
  11. --   Copyright (C) 1992,1993,1994,1995,1996 Free Software Foundation, Inc.  --
  12. --                                                                          --
  13. -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  14. -- terms of the  GNU General Public License as published  by the Free Soft- --
  15. -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
  16. -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  17. -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  18. -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  19. -- for  more details.  You should have  received  a copy of the GNU General --
  20. -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
  21. -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
  22. -- MA 02111-1307, USA.                                                      --
  23. --                                                                          --
  24. -- As a special exception,  if other files  instantiate  generics from this --
  25. -- unit, or you link  this unit with other files  to produce an executable, --
  26. -- this  unit  does not  by itself cause  the resulting  executable  to  be --
  27. -- covered  by the  GNU  General  Public  License.  This exception does not --
  28. -- however invalidate  any other reasons why  the executable file  might be --
  29. -- covered by the  GNU Public License.                                      --
  30. --                                                                          --
  31. -- GNAT was originally developed  by the GNAT team at  New York University. --
  32. -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
  33. --                                                                          --
  34. ------------------------------------------------------------------------------
  35.  
  36. --  The body of Interfaces.COBOL is implementation independent (i.e. the
  37. --  same version is used with all versions of GNAT). The specialization
  38. --  to a particular COBOL format is completely contained in the private
  39. --  part ot the spec.
  40.  
  41. with Interfaces; use Interfaces;
  42. with System;     use System;
  43. with Unchecked_Conversion;
  44.  
  45. package body Interfaces.COBOL is
  46.  
  47.    -----------------------------------------------
  48.    -- Declarations for External Binary Handling --
  49.    -----------------------------------------------
  50.  
  51.    subtype B1 is Byte_Array (1 .. 1);
  52.    subtype B2 is Byte_Array (1 .. 2);
  53.    subtype B4 is Byte_Array (1 .. 4);
  54.    subtype B8 is Byte_Array (1 .. 8);
  55.    --  Representations for 1,2,4,8 byte binary values
  56.  
  57.    function To_B1 is new Unchecked_Conversion (Integer_8,  B1);
  58.    function To_B2 is new Unchecked_Conversion (Integer_16, B2);
  59.    function To_B4 is new Unchecked_Conversion (Integer_32, B4);
  60.    function To_B8 is new Unchecked_Conversion (Integer_64, B8);
  61.    --  Conversions from native binary to external binary
  62.  
  63.    function From_B1 is new Unchecked_Conversion (B1, Integer_8);
  64.    function From_B2 is new Unchecked_Conversion (B2, Integer_16);
  65.    function From_B4 is new Unchecked_Conversion (B4, Integer_32);
  66.    function From_B8 is new Unchecked_Conversion (B8, Integer_64);
  67.    --  Conversions from external binary to signed native binary
  68.  
  69.    function From_B1U is new Unchecked_Conversion (B1, Unsigned_8);
  70.    function From_B2U is new Unchecked_Conversion (B2, Unsigned_16);
  71.    function From_B4U is new Unchecked_Conversion (B4, Unsigned_32);
  72.    function From_B8U is new Unchecked_Conversion (B8, Unsigned_64);
  73.    --  Conversions from external binary to unsigned native binary
  74.  
  75.    -----------------------
  76.    -- Local Subprograms --
  77.    -----------------------
  78.  
  79.    function Binary_To_Decimal
  80.      (Item   : Byte_Array;
  81.       Format : Binary_Format)
  82.       return   Integer_64;
  83.    --  This function converts a numeric value in the given format to its
  84.    --  corresponding integer value. This is the non-generic implementation
  85.    --  of Decimal_Conversions.To_Decimal. The generic routine does the
  86.    --  final conversion to the fixed-point format.
  87.  
  88.    function Numeric_To_Decimal
  89.      (Item   : Numeric;
  90.       Format : Display_Format)
  91.       return   Integer_64;
  92.    --  This function converts a numeric value in the given format to its
  93.    --  corresponding integer value. This is the non-generic implementation
  94.    --  of Decimal_Conversions.To_Decimal. The generic routine does the
  95.    --  final conversion to the fixed-point format.
  96.  
  97.    function Packed_To_Decimal
  98.      (Item   : Packed_Decimal;
  99.       Format : Packed_Format)
  100.       return   Integer_64;
  101.    --  This function converts a packed value in the given format to its
  102.    --  corresponding integer value. This is the non-generic implementation
  103.    --  of Decimal_Conversions.To_Decimal. The generic routine does the
  104.    --  final conversion to the fixed-point format.
  105.  
  106.    procedure Swap (B : in out Byte_Array; F : Binary_Format);
  107.    --  Swaps the bytes if required by the binary format F
  108.  
  109.    function To_Display
  110.      (Item   : Integer_64;
  111.       Format : Display_Format;
  112.       Length : Natural)
  113.       return   Numeric;
  114.    --  This function converts the given integer value into display format,
  115.    --  using the given format, with the length in bytes of the result given
  116.    --  by the last parameter. This is the non-generic implementation of
  117.    --  Decimal_Conversions.To_Display. The conversion of the item from its
  118.    --  original decimal format to Integer_64 is done by the generic routine.
  119.  
  120.    function To_Packed
  121.      (Item   : Integer_64;
  122.       Format : Packed_Format;
  123.       Length : Natural)
  124.       return   Packed_Decimal;
  125.    --  This function converts the given integer value into packed format,
  126.    --  using the given format, with the length in digits of the result given
  127.    --  by the last parameter. This is the non-generic implementation of
  128.    --  Decimal_Conversions.To_Display. The conversion of the item from its
  129.    --  original decimal format to Integer_64 is done by the generic routine.
  130.  
  131.    function Valid_Binary (Item : in Byte_Array) return Boolean;
  132.    --  This is the non-generic implementation of Decimal_Conversions.Valid
  133.    --  for the binary case.
  134.  
  135.    function Valid_Numeric
  136.      (Item   : Numeric;
  137.       Format : Display_Format)
  138.       return   Boolean;
  139.    --  This is the non-generic implementation of Decimal_Conversions.Valid
  140.    --  for the display case.
  141.  
  142.    function Valid_Packed
  143.      (Item   : Packed_Decimal;
  144.       Format : Packed_Format)
  145.       return   Boolean;
  146.    --  This is the non-generic implementation of Decimal_Conversions.Valid
  147.    --  for the packed case.
  148.  
  149.    -----------------------
  150.    -- Binary_To_Decimal --
  151.    -----------------------
  152.  
  153.    function Binary_To_Decimal
  154.      (Item   : Byte_Array;
  155.       Format : Binary_Format)
  156.       return   Integer_64
  157.    is
  158.       Len : constant Natural := Item'Length;
  159.       R   : Byte_Array (1 .. Len) := Item;
  160.  
  161.    begin
  162.       if not Valid_Binary (Item) then
  163.          raise Conversion_Error;
  164.       end if;
  165.  
  166.       if Len = 1 then
  167.          if Format in Binary_Unsigned_Format then
  168.             return Integer_64 (From_B1U (Item));
  169.          else
  170.             return Integer_64 (From_B1 (Item));
  171.          end if;
  172.  
  173.       elsif Len = 2 then
  174.          declare
  175.             R : B2 := Item;
  176.  
  177.          begin
  178.             Swap (R, Format);
  179.  
  180.             if Format in Binary_Unsigned_Format then
  181.                return Integer_64 (From_B2U (R));
  182.             else
  183.                return Integer_64 (From_B2 (R));
  184.             end if;
  185.          end;
  186.  
  187.       elsif Len = 4 then
  188.          declare
  189.             R : B4 := Item;
  190.  
  191.          begin
  192.             Swap (R, Format);
  193.  
  194.             if Format in Binary_Unsigned_Format then
  195.                return Integer_64 (From_B4U (R));
  196.             else
  197.                return Integer_64 (From_B4 (R));
  198.             end if;
  199.          end;
  200.  
  201.       else -- Len = 8
  202.          declare
  203.             R : B8 := Item;
  204.  
  205.          begin
  206.             Swap (R, Format);
  207.  
  208.             if Format in Binary_Unsigned_Format then
  209.                return Integer_64 (From_B8U (R));
  210.             else
  211.                return Integer_64 (From_B8 (R));
  212.             end if;
  213.          end;
  214.       end if;
  215.    end Binary_To_Decimal;
  216.  
  217.    ------------------------
  218.    -- Numeric_To_Decimal --
  219.    ------------------------
  220.  
  221.    --  The following assumptions are made in the coding of this routine
  222.  
  223.    --    The range of COBOL_Digits is compact and the ten values
  224.    --    represent the digits 0-9 in sequence
  225.  
  226.    --    The range of COBOL_Plus_Digits is compact and the ten values
  227.    --    represent the digits 0-9 in sequence with a plus sign.
  228.  
  229.    --    The range of COBOL_Minus_Digits is compact and the ten values
  230.    --    represent the digits 0-9 in sequence with a minus sign.
  231.  
  232.    --    The COBOL_Minus_Digits set is disjoint from COBOL_Digits
  233.  
  234.    --  These assumptions are true for all COBOL representations we know of.
  235.  
  236.    function Numeric_To_Decimal
  237.      (Item   : Numeric;
  238.       Format : Display_Format)
  239.       return   Integer_64
  240.    is
  241.       Sign   : COBOL_Character := COBOL_Plus;
  242.       Result : Integer_64 := 0;
  243.  
  244.    begin
  245.       if not Valid_Numeric (Item, Format) then
  246.          raise Conversion_Error;
  247.       end if;
  248.  
  249.       for J in reverse Item'Range loop
  250.          declare
  251.             K : constant COBOL_Character := Item (J);
  252.  
  253.          begin
  254.             if K in COBOL_Digits then
  255.                Result := Result * 10 +
  256.                            (COBOL_Character'Pos (K) -
  257.                              COBOL_Character'Pos (COBOL_Digits'First));
  258.  
  259.             elsif K in COBOL_Plus_Digits then
  260.                Result := Result * 10 +
  261.                            (COBOL_Character'Pos (K) -
  262.                              COBOL_Character'Pos (COBOL_Plus_Digits'First));
  263.  
  264.             elsif K in COBOL_Minus_Digits then
  265.                Result := Result * 10 +
  266.                            (COBOL_Character'Pos (K) -
  267.                              COBOL_Character'Pos (COBOL_Minus_Digits'First));
  268.                Sign := COBOL_Minus;
  269.  
  270.             --  Only remaining possibility is COBOL_Plus or COBOL_Minus
  271.  
  272.             else
  273.                Sign := K;
  274.             end if;
  275.          end;
  276.       end loop;
  277.  
  278.       if Sign = COBOL_Plus then
  279.          return Result;
  280.       else
  281.          return -Result;
  282.       end if;
  283.  
  284.    exception
  285.       when Constraint_Error =>
  286.          raise Conversion_Error;
  287.  
  288.    end Numeric_To_Decimal;
  289.  
  290.    -----------------------
  291.    -- Packed_To_Decimal --
  292.    -----------------------
  293.  
  294.    function Packed_To_Decimal
  295.      (Item   : Packed_Decimal;
  296.       Format : Packed_Format)
  297.       return   Integer_64
  298.    is
  299.       Result : Integer_64 := 0;
  300.       Sign   : constant Decimal_Element := Item (Item'Last);
  301.  
  302.    begin
  303.       if not Valid_Packed (Item, Format) then
  304.          raise Conversion_Error;
  305.       end if;
  306.  
  307.       case Packed_Representation is
  308.          when IBM =>
  309.             for J in reverse Item'First .. Item'Last - 1 loop
  310.                Result := Result * 10 + Integer_64 (Item (J));
  311.             end loop;
  312.  
  313.             if Sign = 16#0B# or else Sign = 16#0D# then
  314.                return -Result;
  315.             else
  316.                return +Result;
  317.             end if;
  318.       end case;
  319.  
  320.    exception
  321.       when Constraint_Error =>
  322.          raise Conversion_Error;
  323.    end Packed_To_Decimal;
  324.  
  325.    ----------
  326.    -- Swap --
  327.    ----------
  328.  
  329.    procedure Swap (B : in out Byte_Array; F : Binary_Format) is
  330.    begin
  331.       --  Return if no swap needed
  332.  
  333.       case F is
  334.          when H | HU =>
  335.             if System.Default_Bit_Order = System.High_Order_First then
  336.                return;
  337.             end if;
  338.  
  339.          when L | LU =>
  340.             if System.Default_Bit_Order = System.Low_Order_First then
  341.                return;
  342.             end if;
  343.  
  344.          when N | NU =>
  345.             return;
  346.       end case;
  347.  
  348.       --  Here a swap is needed
  349.  
  350.       declare
  351.          Len : constant Natural := B'Length;
  352.  
  353.       begin
  354.          if Len = 1 then
  355.             null;
  356.  
  357.          elsif Len = 2 then
  358.             B := B2'(B (2), B (1));
  359.  
  360.          elsif Len = 4 then
  361.             B := B4'(B (4), B (3), B (2), B (1));
  362.  
  363.          else --  B = 8
  364.             B := B8'(B (8), B (7), B (6), B (5),
  365.                      B (4), B (3), B (2), B (1));
  366.          end if;
  367.       end;
  368.    end Swap;
  369.  
  370.    -----------------------
  371.    -- To_Ada (function) --
  372.    -----------------------
  373.  
  374.    function To_Ada (Item : Alphanumeric) return String is
  375.       Result : String (Item'Range);
  376.  
  377.    begin
  378.       for J in Item'Range loop
  379.          Result (J) := COBOL_To_Ada (Item (J));
  380.       end loop;
  381.  
  382.       return Result;
  383.    end To_Ada;
  384.  
  385.    ------------------------
  386.    -- To_Ada (procedure) --
  387.    ------------------------
  388.  
  389.    procedure To_Ada
  390.      (Item   : Alphanumeric;
  391.       Target : out String;
  392.       Last   : out Natural)
  393.    is
  394.       Last_Val : Integer;
  395.  
  396.    begin
  397.       if Item'Length > Target'Length then
  398.          raise Constraint_Error;
  399.       end if;
  400.  
  401.       Last_Val := Target'First - 1;
  402.       for J in Item'Range loop
  403.          Last_Val := Last_Val + 1;
  404.          Target (Last_Val) := COBOL_To_Ada (Item (J));
  405.       end loop;
  406.  
  407.       Last := Last_Val;
  408.    end To_Ada;
  409.  
  410.    -------------------------
  411.    -- To_COBOL (function) --
  412.    -------------------------
  413.  
  414.    function To_COBOL (Item : String) return Alphanumeric is
  415.       Result : Alphanumeric (Item'Range);
  416.  
  417.    begin
  418.       for J in Item'Range loop
  419.          Result (J) := Ada_To_COBOL (Item (J));
  420.       end loop;
  421.  
  422.       return Result;
  423.    end To_COBOL;
  424.  
  425.    --------------------------
  426.    -- To_COBOL (procedure) --
  427.    --------------------------
  428.  
  429.    procedure To_COBOL
  430.      (Item   : String;
  431.       Target : out Alphanumeric;
  432.       Last   : out Natural)
  433.    is
  434.       Last_Val : Integer;
  435.  
  436.    begin
  437.       if Item'Length > Target'Length then
  438.          raise Constraint_Error;
  439.       end if;
  440.  
  441.       Last_Val := Target'First - 1;
  442.       for J in Item'Range loop
  443.          Last_Val := Last_Val + 1;
  444.          Target (Last_Val) := Ada_To_COBOL (Item (J));
  445.       end loop;
  446.  
  447.       Last := Last_Val;
  448.    end To_COBOL;
  449.  
  450.    ----------------
  451.    -- To_Display --
  452.    ----------------
  453.  
  454.    function To_Display
  455.      (Item   : Integer_64;
  456.       Format : Display_Format;
  457.       Length : Natural)
  458.       return   Numeric
  459.    is
  460.       Result : Numeric (1 .. Length);
  461.       Val    : Integer_64 := Item;
  462.  
  463.       procedure Convert (First, Last : Natural);
  464.       --  Convert the number in Val into COBOL_Digits, storing the result
  465.       --  in Result (First .. Last). Raise Conversion_Error if too large.
  466.  
  467.       procedure Embed_Sign (Loc : Natural);
  468.       --  Used for the nonseparate formats to embed the appropriate sign
  469.       --  at the specified location (i.e. at Result (Loc))
  470.  
  471.       procedure Convert (First, Last : Natural) is
  472.          J : Natural := Last;
  473.  
  474.       begin
  475.          while J >= First loop
  476.             Result (J) :=
  477.               COBOL_Character'Val
  478.                 (COBOL_Character'Pos (COBOL_Digits'First) +
  479.                                                    Integer (Val mod 10));
  480.             Val := Val / 10;
  481.  
  482.             if Val = 0 then
  483.                for K in First .. J - 1 loop
  484.                   Result (J) := COBOL_Digits'First;
  485.                end loop;
  486.  
  487.                return;
  488.  
  489.             else
  490.                J := J - 1;
  491.             end if;
  492.          end loop;
  493.  
  494.          raise Conversion_Error;
  495.       end Convert;
  496.  
  497.       procedure Embed_Sign (Loc : Natural) is
  498.          Digit : Natural range 0 .. 9;
  499.  
  500.       begin
  501.          Digit := COBOL_Character'Pos (Result (Loc)) -
  502.                   COBOL_Character'Pos (COBOL_Digits'First);
  503.  
  504.          if Item >= 0 then
  505.             Result (Loc) :=
  506.               COBOL_Character'Val
  507.                 (COBOL_Character'Pos (COBOL_Plus_Digits'First) + Digit);
  508.          else
  509.             Result (Loc) :=
  510.               COBOL_Character'Val
  511.                 (COBOL_Character'Pos (COBOL_Minus_Digits'First) + Digit);
  512.          end if;
  513.       end Embed_Sign;
  514.  
  515.    --  Start of processing for To_Display
  516.  
  517.    begin
  518.       case Format is
  519.          when Unsigned =>
  520.             if Val < 0 then
  521.                raise Conversion_Error;
  522.             else
  523.                Convert (1, Length);
  524.             end if;
  525.  
  526.          when Leading_Separate =>
  527.             if Val < 0 then
  528.                Result (1) := COBOL_Minus;
  529.                Val := -Val;
  530.             else
  531.                Result (1) := COBOL_Plus;
  532.             end if;
  533.  
  534.             Convert (2, Length);
  535.  
  536.          when Trailing_Separate =>
  537.             if Val < 0 then
  538.                Result (Length) := COBOL_Minus;
  539.                Val := -Val;
  540.             else
  541.                Result (Length) := COBOL_Plus;
  542.             end if;
  543.  
  544.             Convert (1, Length - 1);
  545.  
  546.          when Leading_Nonseparate =>
  547.             Val := abs Val;
  548.             Convert (1, Length);
  549.             Embed_Sign (1);
  550.  
  551.          when Trailing_Nonseparate =>
  552.             Val := abs Val;
  553.             Convert (1, Length);
  554.             Embed_Sign (Length);
  555.  
  556.       end case;
  557.  
  558.       return Result;
  559.    end To_Display;
  560.  
  561.    ---------------
  562.    -- To_Packed --
  563.    ---------------
  564.  
  565.    function To_Packed
  566.      (Item   : Integer_64;
  567.       Format : Packed_Format;
  568.       Length : Natural)
  569.       return   Packed_Decimal
  570.    is
  571.       Result : Packed_Decimal (1 .. Length);
  572.       Val    : Integer_64 := abs Item;
  573.  
  574.       procedure Convert (First, Last : Natural);
  575.       --  Convert the number in Val into a sequence of Decimal_Element values,
  576.       --  storing the result in Result (First .. Last). Raise Conversion_Error
  577.       --  if the value is too large to fit.
  578.  
  579.       procedure Convert (First, Last : Natural) is
  580.          J : Natural := Last;
  581.  
  582.       begin
  583.          while J >= First loop
  584.             Result (J) := Decimal_Element (Val mod 10);
  585.             Val := Val / 10;
  586.  
  587.             if Val = 0 then
  588.                for K in First .. J - 1 loop
  589.                   Result (J) := 0;
  590.                end loop;
  591.  
  592.                return;
  593.  
  594.             else
  595.                J := J - 1;
  596.             end if;
  597.          end loop;
  598.  
  599.          raise Conversion_Error;
  600.       end Convert;
  601.  
  602.    --  Start of processing for To_Packed
  603.  
  604.    begin
  605.       case Packed_Representation is
  606.          when IBM =>
  607.             if Format = Packed_Unsigned then
  608.                if Item < 0 then
  609.                   raise Conversion_Error;
  610.                else
  611.                   Result (Length) := 16#F#;
  612.                   Val := Item;
  613.                end if;
  614.  
  615.             elsif Item >= 0 then
  616.                Result (Length) := 16#C#;
  617.  
  618.             else -- Item < 0
  619.                Result (Length) := 16#D#;
  620.             end if;
  621.  
  622.             Convert (1, Length - 1);
  623.             return Result;
  624.       end case;
  625.    end To_Packed;
  626.  
  627.    ------------------
  628.    -- Valid_Binary --
  629.    ------------------
  630.  
  631.    --  Note: we assume twos complement format, and there are no invalid
  632.    --  bit patterns for binary values. The only check we make is that
  633.    --  the length is appropriate (1, 2, 4, or 8)
  634.  
  635.    function Valid_Binary (Item : Byte_Array) return Boolean is
  636.       Len : constant Natural := Item'Length;
  637.  
  638.    begin
  639.       return Len = 1 or else Len = 2 or else Len = 4 or else Len = 8;
  640.    end Valid_Binary;
  641.  
  642.    -------------------
  643.    -- Valid_Numeric --
  644.    -------------------
  645.  
  646.    function Valid_Numeric
  647.      (Item   : Numeric;
  648.       Format : Display_Format)
  649.       return   Boolean
  650.    is
  651.    begin
  652.       --  All character positions except first and last must be Digits.
  653.       --  This is true for all the formats.
  654.  
  655.       for J in Item'First + 1 .. Item'Last - 1 loop
  656.          if Item (J) not in COBOL_Digits then
  657.             return False;
  658.          end if;
  659.       end loop;
  660.  
  661.       case Format is
  662.          when Unsigned =>
  663.             return Item (Item'First) in COBOL_Digits
  664.               and then Item (Item'Last) in COBOL_Digits;
  665.  
  666.          when Leading_Separate =>
  667.             return (Item (Item'First) = COBOL_Plus or else
  668.                     Item (Item'First) = COBOL_Minus)
  669.               and then Item (Item'Last) in COBOL_Digits;
  670.  
  671.          when Trailing_Separate =>
  672.             return Item (Item'First) in COBOL_Digits
  673.               and then
  674.                 (Item (Item'Last) = COBOL_Plus or else
  675.                  Item (Item'Last) = COBOL_Minus);
  676.  
  677.          when Leading_Nonseparate =>
  678.             return (Item (Item'First) in COBOL_Plus_Digits or else
  679.                     Item (Item'First) in COBOL_Minus_Digits)
  680.               and then Item (Item'Last) in COBOL_Digits;
  681.  
  682.          when Trailing_Nonseparate =>
  683.             return Item (Item'First) in COBOL_Digits
  684.               and then
  685.                 (Item (Item'Last) in COBOL_Plus_Digits or else
  686.                  Item (Item'Last) in COBOL_Minus_Digits);
  687.  
  688.       end case;
  689.    end Valid_Numeric;
  690.  
  691.    ------------------
  692.    -- Valid_Packed --
  693.    ------------------
  694.  
  695.    function Valid_Packed
  696.      (Item   : Packed_Decimal;
  697.       Format : Packed_Format)
  698.       return   Boolean
  699.    is
  700.    begin
  701.       case Packed_Representation is
  702.          when IBM =>
  703.             for J in Item'First .. Item'Last - 1 loop
  704.                if Item (J) > 9 then
  705.                   return False;
  706.                end if;
  707.             end loop;
  708.  
  709.             --  For unsigned, sign digit must be F
  710.  
  711.             if Format = Packed_Unsigned then
  712.                return Item (Item'Last) = 16#F#;
  713.  
  714.  
  715.             --  For signed, accept all standard and non-standard signs
  716.  
  717.             else
  718.                return Item (Item'Last) in 16#A# .. 16#F#;
  719.             end if;
  720.       end case;
  721.    end Valid_Packed;
  722.  
  723.    -------------------------
  724.    -- Decimal_Conversions --
  725.    -------------------------
  726.  
  727.    package body Decimal_Conversions is
  728.  
  729.       ---------------------
  730.       -- Length (binary) --
  731.       ---------------------
  732.  
  733.       --  Note that the tests here are all compile time tests
  734.  
  735.       function Length (Format : Binary_Format) return Natural is
  736.       begin
  737.          if Num'Digits <= 2 then
  738.             return 1;
  739.  
  740.          elsif Num'Digits <= 4 then
  741.             return 2;
  742.  
  743.          elsif Num'Digits <= 9 then
  744.             return 4;
  745.  
  746.          else -- Num'Digits in 10 .. 18
  747.             return 8;
  748.          end if;
  749.       end Length;
  750.  
  751.       ----------------------
  752.       -- Length (display) --
  753.       ----------------------
  754.  
  755.       function Length (Format : Display_Format) return Natural is
  756.       begin
  757.          if Format = Leading_Separate or else Format = Trailing_Separate then
  758.             return Num'Digits + 1;
  759.          else
  760.             return Num'Digits;
  761.          end if;
  762.       end Length;
  763.  
  764.       ---------------------
  765.       -- Length (packed) --
  766.       ---------------------
  767.  
  768.       --  Note that the tests here are all compile time checks
  769.  
  770.       function Length
  771.         (Format : Packed_Format)
  772.          return   Natural
  773.       is
  774.       begin
  775.          case Packed_Representation is
  776.             when IBM =>
  777.                return (Num'Digits + 2) / 2 * 2;
  778.          end case;
  779.       end Length;
  780.  
  781.       ---------------
  782.       -- To_Binary --
  783.       ---------------
  784.  
  785.       function To_Binary (Item : Num) return Binary is
  786.       begin
  787.          return Binary (Item);
  788.       end To_Binary;
  789.  
  790.       -------------
  791.       -- To_Comp --
  792.       -------------
  793.  
  794.       --  Note that these tests are all done at compile time
  795.  
  796.       function To_Comp
  797.         (Item   : Num;
  798.          Format : Binary_Format)
  799.          return   Byte_Array
  800.       is
  801.       begin
  802.          if Num'Digits <= 2 then
  803.             return To_B1 (Integer_8'Integer_Value (Item));
  804.  
  805.          elsif Num'Digits <= 4 then
  806.             declare
  807.                R : B2 := To_B2 (Integer_16'Integer_Value (Item));
  808.  
  809.             begin
  810.                Swap (R, Format);
  811.                return R;
  812.             end;
  813.  
  814.          elsif Num'Digits <= 9 then
  815.             declare
  816.                R : B4 := To_B4 (Integer_32'Integer_Value (Item));
  817.  
  818.             begin
  819.                Swap (R, Format);
  820.                return R;
  821.             end;
  822.  
  823.          else -- Num'Digits in 10 .. 16
  824.             declare
  825.                R : B8 := To_B8 (Integer_64'Integer_Value (Item));
  826.  
  827.             begin
  828.                Swap (R, Format);
  829.                return R;
  830.             end;
  831.          end if;
  832.       end To_Comp;
  833.  
  834.       -------------------------
  835.       -- To_Decimal (binary) --
  836.       -------------------------
  837.  
  838.       function To_Decimal
  839.         (Item   : Byte_Array;
  840.          Format : Binary_Format)
  841.          return   Num
  842.       is
  843.       begin
  844.          return Num'Fixed_Value (Binary_To_Decimal (Item, Format));
  845.       end To_Decimal;
  846.  
  847.       ----------------------------------
  848.       -- To_Decimal (internal binary) --
  849.       ----------------------------------
  850.  
  851.       function To_Decimal (Item : Binary) return Num is
  852.       begin
  853.          return Num (Item);
  854.       end To_Decimal;
  855.  
  856.       --------------------------
  857.       -- To_Decimal (display) --
  858.       --------------------------
  859.  
  860.       function To_Decimal
  861.         (Item   : Numeric;
  862.          Format : Display_Format)
  863.          return   Num
  864.       is
  865.       begin
  866.          return Num'Fixed_Value (Numeric_To_Decimal (Item, Format));
  867.       end To_Decimal;
  868.  
  869.       ---------------------------------------
  870.       -- To_Decimal (internal long binary) --
  871.       ---------------------------------------
  872.  
  873.       function To_Decimal (Item : Long_Binary) return Num is
  874.       begin
  875.          return Num (Item);
  876.       end To_Decimal;
  877.  
  878.       -------------------------
  879.       -- To_Decimal (packed) --
  880.       -------------------------
  881.  
  882.       function To_Decimal
  883.         (Item   : Packed_Decimal;
  884.          Format : Packed_Format)
  885.          return   Num
  886.       is
  887.       begin
  888.          return Num'Fixed_Value (Packed_To_Decimal (Item, Format));
  889.       end To_Decimal;
  890.  
  891.       ----------------
  892.       -- To_Display --
  893.       ----------------
  894.  
  895.       function To_Display
  896.         (Item   : Num;
  897.          Format : Display_Format)
  898.          return   Numeric
  899.       is
  900.       begin
  901.          return
  902.            To_Display
  903.              (Integer_64'Integer_Value (Item),
  904.               Format,
  905.               Length (Format));
  906.       end To_Display;
  907.  
  908.       --------------------
  909.       -- To_Long_Binary --
  910.       --------------------
  911.  
  912.       function To_Long_Binary (Item : Num) return Long_Binary is
  913.       begin
  914.          return Long_Binary (Item);
  915.       end To_Long_Binary;
  916.  
  917.       ---------------
  918.       -- To_Packed --
  919.       ---------------
  920.  
  921.       function To_Packed
  922.         (Item   : Num;
  923.          Format : Packed_Format)
  924.          return   Packed_Decimal
  925.       is
  926.       begin
  927.          return
  928.            To_Packed
  929.              (Integer_64'Integer_Value (Item),
  930.               Format,
  931.               Length (Format));
  932.       end To_Packed;
  933.  
  934.       --------------------
  935.       -- Valid (binary) --
  936.       --------------------
  937.  
  938.       function Valid
  939.         (Item   : Byte_Array;
  940.          Format : Binary_Format)
  941.          return   Boolean
  942.       is
  943.       begin
  944.          return Valid_Binary (Item);
  945.       end Valid;
  946.  
  947.       ---------------------
  948.       -- Valid (display) --
  949.       ---------------------
  950.  
  951.       function Valid
  952.         (Item   : Numeric;
  953.          Format : Display_Format)
  954.          return   Boolean
  955.       is
  956.       begin
  957.          return Valid_Numeric (Item, Format);
  958.       end Valid;
  959.  
  960.       --------------------
  961.       -- Valid (packed) --
  962.       --------------------
  963.  
  964.       function Valid
  965.         (Item   : Packed_Decimal;
  966.          Format : Packed_Format)
  967.          return   Boolean
  968.       is
  969.       begin
  970.          return Valid_Packed (Item, Format);
  971.       end Valid;
  972.  
  973.    end Decimal_Conversions;
  974.  
  975. end Interfaces.COBOL;
  976.